package com.xlx.users.service.impl;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.jwt.JWT;
import com.alibaba.nacos.shaded.io.grpc.netty.shaded.io.netty.util.internal.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xlx.common.utils.JsonResult;
import com.xlx.common.utils.UsersLoginKey;
import com.xlx.users.entity.dto.LoginDTO;
import com.xlx.users.entity.pojo.ThFollow;
import com.xlx.users.entity.pojo.ThUsers;
import com.xlx.users.entity.vo.RecommendationVO;
import com.xlx.users.mapper.ThFollowMapper;
import com.xlx.users.mapper.ThUsersMapper;
import com.xlx.users.service.ThUsersService;
import com.xlx.users.utils.BaseContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author xieluxing
 * @since 2023-01-29
 */
@Service
@Slf4j
public class ThUsersServiceImpl extends ServiceImpl<ThUsersMapper, ThUsers> implements ThUsersService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ThUsersMapper thUsersMapper;

    @Autowired
    private ThFollowMapper thFollowMapper;

    /**
     * 模拟发短信验证码
     * 防止有人恶意刷短信，所以短时间内限定短信发送次数
     *
     * @param loginDTO
     * @return
     */
    @Override
    public JsonResult successMsg(LoginDTO loginDTO) {
        // 作为redis的key设置一般为：项目名+模块名+业务+自定特殊字符
        String sendCountKey = "tanhua:member:sms:" + loginDTO.getFlag() + ":" + loginDTO.getPhone() + ":count";
        String key = "tanhua:member:sms:" + loginDTO.getFlag() + ":" + loginDTO.getPhone();
        // 判断这个场景下累计发送了几次短信
        Integer count = 0;
        if (redisTemplate.hasKey(sendCountKey)) {
            count = Integer.parseInt(redisTemplate.opsForValue().get(sendCountKey) + "");
            log.info("发送次数：{}", count);
        }
        if (count > 10) {
            // 报错
            return JsonResult.error(loginDTO.getFlag() + "场景，发送短信过多");
        }

        LambdaQueryWrapper<ThUsers> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ThUsers::getPhone, loginDTO.getPhone());
        ThUsers thUsers = thUsersMapper.selectOne(wrapper);
        if (thUsers == null) {
            ThUsers user = new ThUsers();
            user.setPhone(loginDTO.getPhone());
            thUsersMapper.insert(user);
        }

        // 发送短信
        String msg = RandomUtil.randomString(6);
        log.info("验证码：{}", msg);
        // 存入redis
        redisTemplate.opsForValue().set(key, msg, 90, TimeUnit.SECONDS);
        // 更新统计次数
        redisTemplate.opsForValue().set(sendCountKey, count + 1, 1, TimeUnit.DAYS);

        return JsonResult.success("验证码为:" + msg);
    }

    /**
     * 手机验证码登录
     *
     * @param loginDTO
     * @return
     */
    @Override
    public JsonResult usersLogin(LoginDTO loginDTO) {
        String key = "tanhua:member:sms:" + loginDTO.getFlag() + ":" + loginDTO.getPhone();
        LambdaQueryWrapper<ThUsers> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ThUsers::getPhone, loginDTO.getPhone());
        ThUsers thUsers = thUsersMapper.selectOne(wrapper);

        if (!redisTemplate.hasKey(key)) {
            return JsonResult.error("验证码已过期或错误");
        }
        String msg = redisTemplate.opsForValue().get(key).toString();
        if (!msg.equals(loginDTO.getMsg())) {
            return JsonResult.error("验证码错误");
        }
        String token = JWT.create().setPayload("usersId", thUsers.getUsersId())
                .setPayload("time", System.currentTimeMillis())
                .setKey(UsersLoginKey.USERS_KET.getBytes())
                .sign();
        redisTemplate.opsForValue().set(token, "1", 180, TimeUnit.SECONDS);
        return JsonResult.success(token);
    }

    /**
     * 完善个人信息
     *
     * @param thUsers
     * @return
     */
    @Override
    public JsonResult updateUsers(ThUsers thUsers) {
        String usersId = BaseContext.getCurrentId();
        thUsers.setUsersId(usersId);

        int result = thUsersMapper.updateById(thUsers);
        if (result != 1) {
            return JsonResult.error("失败");
        }
        return JsonResult.success("修改成功");
    }

    /**
     * 添加关注
     *
     * @param thFollow
     * @return
     */
    @Override
    public JsonResult addLike(ThFollow thFollow) {
        String myUsersId = BaseContext.getCurrentId();
        thFollow.setUsersId(myUsersId);
        int result = thFollowMapper.insert(thFollow);

        if (result != 1) {
            return JsonResult.error("关注失败");
        }
        return JsonResult.success("关注成功");
    }

    /**
     * 取消关注
     *
     * @param followId
     * @return
     */
    @Override
    public JsonResult deleteLike(String followId) {
        String myUsersId = BaseContext.getCurrentId();
        LambdaQueryWrapper<ThFollow> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ThFollow::getUsersId, myUsersId)
                .eq(ThFollow::getFollowId, followId);
        ThFollow follow = thFollowMapper.selectOne(wrapper);

        int result = thFollowMapper.deleteById(follow);
        if (result != 1) {
            return JsonResult.error("取消关注失败");
        }
        return JsonResult.success("取消关注成功");
    }

    /**
     * 关注页面分页查询
     *
     * @param name
     * @param page
     * @param size
     * @param type
     * @return
     */
    @Override
    public JsonResult findSearchAll(String name, Integer page, Integer size, Integer type) {
        String myUsersId = BaseContext.getCurrentId();
        LambdaQueryWrapper<ThFollow> userIdWrapper = new LambdaQueryWrapper<>();
        userIdWrapper.eq(ThFollow::getUsersId, myUsersId);
        List<String> follows = new ArrayList<>();
        List<ThFollow> myLikeFollows = thFollowMapper.selectList(userIdWrapper);
        for (ThFollow myLikeFollow : myLikeFollows) {
            follows.add(myLikeFollow.getFollowId());
        }


        List<ThFollow> followList = new ArrayList<>();
        for (String follow : follows) {
            LambdaQueryWrapper<ThFollow> followIdWrapper = new LambdaQueryWrapper<>();
            followIdWrapper.eq(ThFollow::getUsersId, follow)
                    .eq(ThFollow::getFollowId, myUsersId);
            ThFollow thFollow = thFollowMapper.selectOne(followIdWrapper);

            if (thFollow != null) {
                followList.add(thFollow);
            }
        }
        List<String> likeIdList = new ArrayList<>();
        for (ThFollow thFollow : followList) {
            likeIdList.add(thFollow.getUsersId());
        }

        List<ThUsers> thUsers = this.listByIds(likeIdList);
        List<ThUsers> collect;

        // 使用stream对筛选出来的集合进行分页查询
        if (!StringUtils.hasText(name)) {
            collect = thUsers.stream()
                    .skip((long) (page - 1) * size).limit(size)
                    .collect(Collectors.toList());
        } else {
            collect = thUsers.stream()
                    .skip((long) (page - 1) * size).limit(size)
                    .filter(e -> StringUtils.hasText(name) &&
                            e.getNickname().equals(name))
                    .collect(Collectors.toList());
        }

        Page<ThUsers> p = new Page<>();
        p.setRecords(collect);
        p.setCurrent(1);
        p.setTotal(collect.size());
        return JsonResult.success(p);
    }

    /**
     * 首页推荐
     * 根据当前城市，推荐性别不同，年龄差在3岁，按缘分值降序进行首页推荐
     * @return
     */
    @Override
    public JsonResult recommendation() {
        String myUserId = BaseContext.getCurrentId();
        ThUsers thUsers = thUsersMapper.selectById(myUserId);
        Date birthday = thUsers.getBirthday();
        long myBirthdayTime = birthday.getTime();
        LambdaQueryWrapper<ThUsers> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ThUsers::getCity, thUsers.getCity())
                .ne(ThUsers::getGender,thUsers.getGender())
                .orderByDesc(ThUsers::getScore);
        List<ThUsers> allUsers = thUsersMapper.selectList(wrapper);
        List<ThUsers> findUsers = new ArrayList<>();
        for (ThUsers allUser : allUsers) {
            Date allBirthday = allUser.getBirthday();
            long userBthTime = allBirthday.getTime();
            long diff = myBirthdayTime - userBthTime;
            long diffDays = diff / (24 * 60 * 60 * 1000);
            if (diffDays > -1095 && diffDays < 1095) {
                findUsers.add(allUser);
            }
        }
        return JsonResult.success(findUsers);
    }


}
